package main

import (
	"Godzilla/conf/databases"
	"Godzilla/tcp/proto"
	"bufio"
	"fmt"
	"io"
	"log"
	"math/rand"
	"net"
	"sync"
	"time"
)

type Node struct {
	Address     string
	Conn 		*net.TCPConn
	DataQueue	chan []byte
	isConn		bool
}

//连接的客户端
var (
	ClientMap map[string]*Node = make(map[string]*Node, 0)
	RWLocker sync.RWMutex
)



func main()  {
	var (
		tcpServerArr  []string
	)

	//获取服务端
	databases.TcpArrSetConfig()
	tcpServerArr = databases.GetTcpArrConfig()
	//log.Println(tcpServerArr[0])
	log.Println("获取到的TcpServerArr:", tcpServerArr)

	for _, address := range tcpServerArr {
		//服务器地址
		hawkServer, err := net.ResolveTCPAddr("tcp", address)
		if err != nil {
			log.Println("ResolveTCPAddr报错:", err.Error())
		}
		conn, err := net.DialTCP("tcp", nil, hawkServer)
		if err != nil {
			log.Println("连接服务器错误:", err.Error())
			return
		}
		//defer conn.Close()
		//获取conn
		node := &Node{
			Address:  address,
			Conn:      conn,
			DataQueue: make(chan []byte, 128),
			isConn: true,
		}

		RWLocker.Lock()
		ClientMap[address] = node
		RWLocker.Unlock()

		//发送
		go TcpClientSend(node)

		//接收
		go TcpClientReceive(node)

		//for  {
		//	rand.Seed(time.Now().UnixNano())
		//	sleepSecond := rand.Intn(10)
		//	//sleepSecond := 6
		//	log.Println(sleepSecond)
		//	str := address
		//	log.Println(str)
		//	msg := []byte(str)
		//	if node.isConn {
		//		log.Println("发送channel")
		//		node.DataQueue <- msg
		//		//node.Conn.Write([]byte(msg))
		//	}
		//	time.Sleep(time.Duration(sleepSecond) * time.Second)
		//	//node.Conn.Write([]byte("休眠3秒客户端发送消息给服务端"))
		//}
	}

	num := 0
	for {
		address := tcpServerArr[num]
		log.Println(address)
		ClientMap[address].DataQueue <- []byte(address)
		rand.Seed(time.Now().UnixNano())
		sleepSecond := rand.Intn(5)
		time.Sleep(time.Duration(sleepSecond) * time.Second)
		log.Println(sleepSecond)
		if num == 0 {
			num = 1
			if len(tcpServerArr) == 1 {
				num = 0
			}
		} else {
			num= 0
		}
	}


}

// TcpClientSend 发送数据到tcp客户端
func TcpClientSend(node *Node)  {
	timer := time.NewTimer(5 * time.Second)
	defer timer.Stop()
	for  {
		select {
		case data:= <-node.DataQueue:

			b, err := proto.Encode(string(data))
			if err != nil {
				fmt.Println("Encode失败，err:", err)
				return
			}
			node.Conn.Write(b)
			timer.Reset(5 * time.Second)



			//_, err := node.Conn.Write([]byte(data))
			//if err != nil {
			//	log.Println(err.Error())
			//	//return 此处协程里面return会关闭协程
			//}
		case <-timer.C:
			log.Println("超时5秒发送的心跳")
			if node.isConn {

				b, err := proto.Encode("这是心跳")
				if err != nil {
					fmt.Println("Encode失败，err:", err)
				}
				node.Conn.Write(b)
				timer.Reset(5 * time.Second)
			}
		default:
			//log.Println("执行default")
		}
	}
}

// TcpClientReceive 从tcp服务端接收到数据
func TcpClientReceive(node *Node)  {
	for  {
		if !node.isConn {
			return
		}
		//buf := [512]byte{}
		//n, err := node.Conn.Read(buf[:])
		//if err != nil {
		//	log.Println("接收到来自tcp服务端数据报错:", err.Error())
		//	node.isConn = false
		//	node.Conn.Close()
		//}
		//服务端关闭直接返回

		reader := bufio.NewReader(node.Conn)
		msg, err := proto.Decode(reader)

		fmt.Println("收到服务端消息消息：", msg)
		if err == io.EOF {
			return
		}
		if err != nil {
			fmt.Println("decode失败，err:", err)
			return
		}
		if err == io.EOF {
			//TODO 同时把服务端ClientMap删除
			log.Println("tcp服务端关闭了")
			return
		}
		//log.Println("接收到服务端数据:", string(buf[:n]))

	}
}

